

use serde::{Serialize, Deserialize};
use rbatis::rbdc::datetime::DateTime;
use base64::Engine;


#[derive(Debug)]
#[derive(Clone)]
#[derive(lombok::Getter)]
#[derive(Serialize, Deserialize)]
pub struct User
{
    id: u32,
    username: String,
    password: String,
    register_time: DateTime,
    last_login_time: Option<DateTime>,

    nickname: Option<String>,
    signature: String,
    level: u32,
    fans: u32   //粉丝数量
}
impl User
{
    pub fn new(id: u32, username: &str, password: &str, nickname: Option<String>) -> Self {
        Self {
            id,
            username: username.to_string(),
            password: password.to_string(),
            register_time: DateTime::now(),
            last_login_time: Option::None,
            nickname,
            signature: "这个人很懒，没有设置个性签名".to_string(),
            level: 1,
            fans: 0
        }
    }

    pub fn set_last_login_time(&mut self, time: DateTime) { self.last_login_time = Some(time); }
    pub fn username_base64(&self) -> String { base64::prelude::BASE64_STANDARD_NO_PAD.encode(self.username.as_bytes()) }
    pub fn password_base64(&self) -> String { base64::prelude::BASE64_STANDARD_NO_PAD.encode(self.password.as_bytes()) }
}


#[derive(Debug)]
#[derive(Clone)]
#[derive(lombok::Getter)]
#[derive(Serialize)]
pub struct UserDTO
{
    id: u32,
    username: String,
    register_time: DateTime,
    last_login_time: Option<DateTime>,

    nickname: Option<String>,
    signature: String,
    level: u32,
    fans: u32   //粉丝数量
}
impl UserDTO
{
    pub fn new(user: User) -> Self
    {
        UserDTO {
            id: user.id,
            username: user.username,
            register_time: user.register_time,
            last_login_time: user.last_login_time,
            nickname: user.nickname,
            signature: user.signature,
            level: user.level,
            fans: user.fans
        }
    }

    pub fn from_user(user: User) -> Self { UserDTO::new(user) }
}


rbatis::crud!(User{});
rbatis::impl_select!(User {select_by_id(id: &str) -> Option => "`where id = #{id} limit 1`"});
rbatis::impl_update!(User {update_by_id(id: &str) => "`where id = #{id}`"});
rbatis::impl_delete!(User {delete_by_id(id: &str) => "`where id = #{id}`"});


#[cfg(test)]
mod tests
{
    use super::*;

    #[test]
    fn test_user_structure()
    {
        let user = User::new(1, "username", "password", Option::Some("nickname".to_string()));
        let User {id, .. } = user;
        println!("user_id: {}", id);
    }
}

